package com.gitee.melin.bee.util;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 * Created by zheng on 2020/9/17
 */
public class ThreadUtils {

    public static ThreadPoolExecutor newDaemonFixedThreadPool(int nThreads, String prefix) {
        ThreadFactory threadFactory = namedThreadFactory(prefix);
        return (ThreadPoolExecutor) Executors.newFixedThreadPool(nThreads, threadFactory);
    }

    public static ExecutorService newDaemonSingleThreadExecutor(String prefix) {
        ThreadFactory threadFactory = namedThreadFactory(prefix);
        return Executors.newSingleThreadExecutor(threadFactory);
    }

    /**
     * Wrapper over ScheduledThreadPoolExecutor.
     */
    public static ScheduledExecutorService newDaemonSingleThreadScheduledExecutor(String prefix) {
        ThreadFactory threadFactory = namedThreadFactory(prefix);
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, threadFactory);
        // By default, a cancelled task is not automatically removed from the work queue until its delay
        // elapses. We have to enable it manually.
        executor.setRemoveOnCancelPolicy(true);
        return executor;
    }

    public static ThreadPoolExecutor newDaemonCachedThreadPool(
            String prefix, int maxThreadNumber, int keepAliveSeconds) {
        ThreadFactory threadFactory =  new ThreadFactoryBuilder().setDaemon(true).setNameFormat(prefix + "-%d").build();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                maxThreadNumber, // corePoolSize: the max number of threads to create before queuing the tasks
                maxThreadNumber, // maximumPoolSize: because we use LinkedBlockingDeque, this one is not used
                keepAliveSeconds,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(),
                threadFactory);
        threadPool.allowCoreThreadTimeOut(true);
        return threadPool;
    }

    public static ThreadFactory namedThreadFactory(String prefix) {
        return new ThreadFactoryBuilder().setDaemon(true).setNameFormat(prefix + "-%d").build();
    }
}
